package code;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import model.MF;
import model.Predict;
import data.Data;
import file.Parsing3Classes;
import file.Parsing3ClassesW2Inputs;

public class TenFoldCrossValidation_SVMModel2 {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		String dir = "D:\\Netflix Dataset\\download\\";
		String epsilon = "15";
		System.out.println("epsilon "+epsilon);
		
		Parsing3Classes parseTrain = new Parsing3Classes(dir+"smalltrain0"+epsilon+"_data",dir+"smalltrain0"+epsilon+"_sign");
		List<Data> train = parseTrain.getList();
		List<Data> postrain = parseTrain.getPos();
		List<Data> negtrain = parseTrain.getNeg();
		
		int k = 5;
		double gamma = 0.02;
		double lambda = 0.02;
		
		MF mf = new MF(k, gamma, lambda, train);
		MF pmf = new MF(k, gamma, lambda, postrain);
		MF nmf = new MF(k, gamma, lambda, negtrain);
		
		Parsing3Classes parseTest = new Parsing3Classes(dir+"smalltest0"+epsilon+"_data","C:\\Users\\mtnguyen.2012\\Downloads\\svm_light_windows (1)\\ordinal_classifier\\fold-1\\groundtruth0"+epsilon+"");
		List<Data> test = parseTest.getList();
		List<Data> postest = parseTest.getPos();
		List<Data> negtest = parseTest.getNeg();
		List<Data> neutest = parseTest.getNeu();
		
		System.out.print("Use MF to predict Test set: ");
		Predict pred = new Predict(test, mf);
		
		System.out.println("For ideal case: ");		

		System.out.println("Percentage of Pos. Test set: " + 100*postest.size()/(double)test.size());
		System.out.println("Percentage of Neu. Test set: " + 100*neutest.size()/(double)test.size());
		System.out.println("Percentage of Neg. Test set: " + 100*negtest.size()/(double)test.size());
		
		System.out.print("User PMF to predict Pos. Test set: ");
		Predict pospred = new Predict(postest, pmf);
		System.out.print("User MF to predict Neu. Test set: ");
		Predict neupred = new Predict(neutest, mf);
		System.out.print("Use NMF to predict Neg. Test set: ");
		Predict negpred = new Predict(negtest, nmf);
		System.out.print("User PMF to predict Pos. Test set, NMF to predict Neg. Test set, MF to predict Neu. Test set: ");
		Predict signpred = new Predict(postest, negtest, neutest, mf, pmf, nmf);
		
		String svm_dir = "C:\\Users\\mtnguyen.2012\\Downloads\\svm_light_windows (1)\\ordinal_classifier\\fold-1\\";
//		Parsing3Classes parseTest2 = new Parsing3Classes(dir+"smalltest015_data","C:\\Users\\mtnguyen.2012\\Downloads\\svm_light_windows (1)\\ordinal_classifier\\finalresult015");
		double margin = 2;
		System.out.println("margin "+margin);
		Parsing3ClassesW2Inputs parseTest2 = new Parsing3ClassesW2Inputs(dir+"smalltest0"+epsilon+"_data", svm_dir+"output0"+epsilon+"", svm_dir+"output0"+epsilon+"_", margin);
		List<Data> test2 = parseTest2.getList();
		List<Data> postest2 = parseTest2.getPos();
		List<Data> negtest2 = parseTest2.getNeg();
		List<Data> neutest2 = parseTest2.getNeu();
//		System.out.println("Neu test size: "+neutest2.size());
		
		System.out.println("Predict from SVM result ");
		
		System.out.println("Percentage pos ratings: " + 100*postest2.size() / (double) test2.size());
		System.out.println("Percentage neu ratings: " + 100*neutest2.size() / (double) test2.size());
		System.out.println("Percentage neg ratings: " + 100*negtest2.size() / (double) test2.size());
		
		System.out.print("Use MF to predict Test set: ");
		Predict pred2 = new Predict(test2, mf);

		System.out.println("For svm-output signs ");
		System.out.print("User PMF to predict Pos. Test set: ");
		Predict pospred2 = new Predict(postest2, pmf);
		System.out.print("User MF to predict Neu. Test set: ");
		Predict neupred2 = new Predict(neutest2, mf);
		System.out.print("Use NMF to predict Neg. Test set: ");
		Predict negpred2 = new Predict(negtest2, nmf);
		System.out.print("User PMF to predict Pos. Test set, NMF to predict Neg. Test set, MF to predict Neu. Test set: ");
		Predict signpred2 = new Predict(postest2, negtest2, neutest2, mf, pmf, nmf);	
		
		String line;
		BufferedReader ground = new BufferedReader(new FileReader(svm_dir+"groundtruth0"+epsilon+""));
		BufferedReader output = new BufferedReader(new FileReader(svm_dir+"output0"+epsilon+""));
		BufferedReader output_ = new BufferedReader(new FileReader(svm_dir+"output0"+epsilon+"_"));
		
		List<Data> pos_as_pos=new ArrayList<Data>();
		List<Data> pos_as_neg=new ArrayList<Data>();
		List<Data> pos_as_neu=new ArrayList<Data>();
		
		List<Data> neg_as_neg=new ArrayList<Data>();
		List<Data> neg_as_pos=new ArrayList<Data>();
		List<Data> neg_as_neu=new ArrayList<Data>();
		
		List<Data> neu_as_pos=new ArrayList<Data>();
		List<Data> neu_as_neg=new ArrayList<Data>();
		List<Data> neu_as_neu=new ArrayList<Data>();
		
		List<Data> neu = new ArrayList<Data>();
		
		Iterator<Data> it = test.iterator();
		
		while((line = ground.readLine()) != null) {
			int gnd = Integer.parseInt(line);
			double res = Double.parseDouble(output.readLine());
			Data datum = it.next();
			
			if(res > 0){
				if(gnd > 0){
					pos_as_pos.add(datum);
				}
				else if (gnd < 0){
					pos_as_neg.add(datum);					
				}
				else {
					pos_as_neu.add(datum);
				}
			}
			else {
				
				res = Double.parseDouble(output_.readLine());

				if (res > 0){
					if(gnd < 0) {
						neg_as_neg.add(datum);
					}
					else if(gnd > 0){
						neg_as_pos.add(datum);					
					}
					else {
						neg_as_neu.add(datum);
					}
				}
				else {
					
					neu.add(datum);
					
					if(gnd > 0){
						neu_as_pos.add(datum);
					}
					else if (gnd < 0){
						neu_as_neg.add(datum);					
					}
					else {
						neu_as_neu.add(datum);
					}
				}
			}
		}
		ground.close();
		output.close();
		output_.close();

		System.out.print("Apply PMF: ");
		Predict pap = new Predict(pos_as_pos, pmf);
		Predict pan = new Predict(pos_as_neg, pmf);
		Predict paz = new Predict(pos_as_neu, pmf);
		
		System.out.print("Apply NMF: ");
		Predict nan = new Predict(neg_as_neg, nmf);
		Predict nap = new Predict(neg_as_pos, nmf);
		Predict naz = new Predict(neg_as_neu, nmf);
		
		System.out.print("Apply MF: ");
		Predict neu_predict = new Predict(neu, mf);
		
		System.out.println("actually pos "+pos_as_pos.size()+","+pos_as_neu.size()+","+pos_as_neg.size());
		System.out.println("actually neu "+neu_as_pos.size()+","+neu_as_neu.size()+","+neu_as_neg.size());
		System.out.println("actually neg "+neg_as_pos.size()+","+neg_as_neu.size()+","+neg_as_neg.size());
		
		System.out.println("actually pos "+100*pos_as_pos.size()/(double)postest2.size()+","+100*pos_as_neu.size()/(double)postest2.size()+","+100*pos_as_neg.size()/(double)postest2.size());
		System.out.println("actually neu "+100*neu_as_pos.size()/(double)neutest2.size()+","+100*neu_as_neu.size()/(double)neutest2.size()+","+100*neu_as_neg.size()/(double)neutest2.size());
		System.out.println("actually neg "+100*neg_as_pos.size()/(double)negtest2.size()+","+100*neg_as_neu.size()/(double)negtest2.size()+","+100*neg_as_neg.size()/(double)negtest2.size());
	}

}
